package com.chujian.framework.starter.aliyun.oss;

import cn.hutool.core.io.IoUtil;
import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.comm.Protocol;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import com.chujian.framework.starter.aliyun.AliyunAccountProperties;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;

/**
 * @author ：chujian
 * @date ：2020-09-27
 * OSS 对象存储客户端
 */
@Slf4j
public class AliOssClient {

    private final AliyunOssProperties ossProperties;
    private final AliyunAccountProperties accountProperties;

    private OSS ossClient;

    public AliOssClient(AliyunAccountProperties accountProperties, AliyunOssProperties ossProperties) {
        this.accountProperties = accountProperties;
        this.ossProperties = ossProperties;

        createOssClient();
    }

    private void createOssClient() {
        // 创建ClientConfiguration。ClientConfiguration是OSSClient的配置类，可配置代理、连接超时、最大连接数等参数。
        ClientBuilderConfiguration conf = new ClientBuilderConfiguration();

        // 设置OSSClient允许打开的最大HTTP连接数，默认为1024个。
        conf.setMaxConnections(200);
        // 设置Socket层传输数据的超时时间，默认为50000毫秒。
        conf.setSocketTimeout(10000);
        // 设置建立连接的超时时间，默认为50000毫秒。
        conf.setConnectionTimeout(10000);
        // 设置从连接池中获取连接的超时时间（单位：毫秒），默认不超时。
        conf.setConnectionRequestTimeout(1000);
        // 设置连接空闲超时时间。超时则关闭连接，默认为60000毫秒。
        conf.setIdleConnectionTime(10000);
        // 设置失败请求重试次数，默认为3次。
        conf.setMaxErrorRetry(5);
        // 设置是否支持将自定义域名作为Endpoint，默认支持。
        conf.setSupportCname(true);
        // 设置是否开启二级域名的访问方式，默认不开启。
        conf.setSLDEnabled(false);
        // 设置连接OSS所使用的协议（HTTP或HTTPS），默认为HTTP。
        conf.setProtocol(Protocol.HTTP);
        // 设置用户代理，指HTTP的User-Agent头，默认为aliyun-sdk-java。
        conf.setUserAgent("aliyun-sdk-java");

        // 设置代理服务器端口。
//        conf.setProxyHost("<yourProxyHost>");
        // 设置代理服务器验证的用户名。
//        conf.setProxyUsername("<yourProxyUserName>");
        // 设置代理服务器验证的密码。
//        conf.setProxyPassword("<yourProxyPassword>");

        // 设置是否开启HTTP重定向，默认开启。
        conf.setRedirectEnable(true);
        // 设置是否开启SSL证书校验，默认开启。
        conf.setVerifySSLEnable(true);

        this.ossClient = new OSSClientBuilder().build(ossProperties.getEndpoint(), accountProperties.getAccessKeyId(), accountProperties.getSecret(), conf);
//        this.ossClient = new OSSClientBuilder().build(ossProperties.getEndpoint(), accountProperties.getAccessKeyId(), accountProperties.getSecret());
    }

    public String putObject(String objectName, InputStream inputStream) {
        return putObject(ossProperties.getDefaultBucket(), objectName, inputStream);
    }

    public String putObject(String bucketName, String objectName, InputStream inputStream) {
        PutObjectResult putObjectResult = ossClient.putObject(bucketName, objectName, inputStream);
        return dealPutResult(bucketName, objectName, putObjectResult);
    }

    public String putObject(String bucketName, String objectName, byte[] bytes) {
        PutObjectResult putObjectResult = ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(bytes));
        return dealPutResult(bucketName, objectName, putObjectResult);
    }

    public String putObject(String bucketName, String objectName, File file) {
        PutObjectRequest request = new PutObjectRequest(bucketName, objectName, file);
        return dealPutResult(bucketName, objectName, ossClient.putObject(request));
    }

    public String dealPutResult(String bucketName, String objectName, PutObjectResult putObjectResult) {
        // https://bucket.oss-cn-shanghai.aliyuncs.com/ques/415b0bd452c048189ea09f192a0c89dc.png
        String url = "https://" + bucketName + "." + getEndPointWithoutProtocol() + "/" + objectName;
        if (putObjectResult.getResponse() != null && putObjectResult.getResponse().getContent() != null) {
            IoUtil.close(putObjectResult.getResponse().getContent());
        }
        return url;
    }

    /**
     * 获取对象，调用者必须关闭返回的流
     *
     * @param bucketName
     * @param objectName
     * @return
     */
    public InputStream getObject(String bucketName, String objectName) {
        OSSObject object = ossClient.getObject(bucketName, objectName);
        return object.getObjectContent();
    }

    public void getObject(String bucketName, String objectName, OnGetObjectListener onGetObjectListener) {
        OSSObject object = ossClient.getObject(bucketName, objectName);
        InputStream content = object.getObjectContent();
        onGetObjectListener.onGetObject(content);
        IoUtil.close(content);
    }

    public void delObj(String url) {
        // https://bucket.oss-cn-shanghai.aliyuncs.com/ques/415b0bd452c048189ea09f192a0c89dc.png
        String bucketName = url.substring(8, url.indexOf(getEndPointWithoutProtocol()) - 1);
        String objectName = url.substring(url.indexOf(".com") + 5);
        delObj(bucketName, objectName);
    }

    public void delObj(String bucketName, String objectName) {
        ossClient.deleteObject(bucketName, objectName);
    }

    private String getEndPointWithoutProtocol() {
        return ossProperties.getEndpoint()
                .replace("http://", "")
                .replace("https://", "");
    }

}
